package com.dtx.qiku.store;

import com.dtx.qiku.utils.ProUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class FileStoreUtils {

    /**
     * 定义仓库，仓库是共享的
     */
    private static Store store;

    /**
     * 获取 项目需要用到的仓库
     * @return
     */
    public static Store getStore(){

        if (store == null){
            store = new FileStore(ProUtils.getProperty("fileStore.dbName"));
        }
        return store;
    }

    /**
     * 插入单条
     * @param tableName
     * @param data
     * @param clz
     * @param <T>
     * @return
     * @throws IOException
     */
    public static  <T> int insert(String tableName,T data,Class<T> clz) throws IOException {

        // 获取 仓库
        getStore();

        // 添加一条数据
        // 读取 表中 已经存在的数据
        List<T> read = store.read(tableName, clz);

        // 判断数据是否为空
        if(read == null || read.isEmpty()){
            read = new ArrayList<>();
        }

        read.add(data);

        // 将数据，写入到磁盘
        store.write(tableName,read);

        return 1;
    }

    public static <T> List<T> select(String tableName,Class<T> clz) throws IOException {
        getStore();

        // 查询数据
        List<T> list = store.read(tableName,clz);


        if(list == null || list.isEmpty()){
            list = new ArrayList<>();
        }

        return list;
    }

    /**
     * 插入多条
     * @param tableName
     * @param data
     * @param clz
     * @param <T>
     * @return
     * @throws IOException
     */
    public static  <T> int insertMany(String tableName,List<T> data,Class<T> clz) throws IOException {

        // 获取 仓库
        getStore();

        // 添加一条数据
        // 读取 表中 已经存在的数据
        List<T> read = store.read(tableName, clz);

        // 判断数据是否为空
        if(read == null || read.isEmpty()){
            read = new ArrayList<>();
        }

        read.addAll(data);

        // 将数据，写入到磁盘
        store.write(tableName,read);

        return data.size();
    }

    /**
     * 删除数据
     * @param tableName
     * @param data
     * @param clz
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> int delete(String tableName,T data,Class<T> clz) throws IOException{

        getStore();

        // 查询数据
        List<T> list = store.read(tableName,clz);

        if(list == null || list.isEmpty()){
            return 0;
        }

        boolean b = list.remove(data);

        if(!b) return 0;

        // 删除成功
        store.write(tableName,list);

        return 1;
    }

    /**
     * 按条件删除数据
     * @param tableName
     * @param predicate
     * @param clz
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> int deleteIf(String tableName, Predicate<T> predicate, Class<T> clz) throws IOException{

        getStore();

        // 查询数据
        List<T> list = store.read(tableName,clz);


        if(list == null || list.isEmpty()){
            return 0;
        }

        // 获取长度

        int len = list.size();

        boolean b = list.removeIf(predicate);

        if(!b) return 0;

        // 删除成功
        store.write(tableName,list);

        return len - list.size();
    }

    /**
     * 修改
     * @param tableName
     * @param predicate
     * @param data
     * @param clz
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> int update(String tableName,Predicate<T> predicate,T data,Class<T> clz) throws IOException{
        getStore();

        // 查询数据
        List<T> list = store.read(tableName,clz);


        if(list == null || list.isEmpty()){
            return 0;
        }


        Stream<T> stream = list.stream().filter(predicate);
        // 根据条件查询满足的数据
        long count = list.stream().filter(predicate).count();

        if (count > 1) throw new RuntimeException("修改的数据对应多条，请检查修改条件");

        T t = stream.filter(predicate).findFirst().orElse(null);

        if(t==null) return 0;

        // 获取元素的索引
        int index = list.indexOf(t);

        list.set(index,data);

        // 更新数据库
        store.write(tableName,list);

        return 1;


    }

    /**
     * 查询单条
     * @param tableName
     * @param predicate
     * @param clz
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> T selectOne(String tableName,Predicate<T> predicate,Class<T> clz) throws IOException {
        getStore();

        // 查询数据
        List<T> list = store.read(tableName,clz);


        if(list == null || list.isEmpty()){
            return null;
        }

        long count = list.stream().filter(predicate).count();
        if (count > 1) {
            throw new RuntimeException("期待查到一条数据，但实际返回了" + count+"调数据");
        }

        return list.stream().findFirst().orElse(null);
    }

    /**
     * 查询多条数据
     * @param tableName
     * @param predicate
     * @param clz
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> List<T> selectMany(String tableName,Predicate<T> predicate,Class<T> clz) throws IOException {

        List<T> list = select(tableName, clz);

        return list.stream().filter(predicate).collect(Collectors.toList());
    }

    /**
     * 查询所有
     * @param tableName
     * @param clz
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> List<T> selectAll(String tableName,Class<T> clz) throws IOException {
        return select(tableName,clz);
    }
}
